package com.reason.gateway.filter;

import com.reason.gateway.service.OauthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;

/**
 * 全局过滤器
 *
 * @author yulongjun
 * @date 2020/6/30 6:24 下午
 */
@Component
public class AuthorizationFilter implements GlobalFilter, Ordered {


    /**
     * 注入service层
     */
    @Autowired
    private OauthService oauthService;


    /**
     * 定义登陆页面的访问地址
     */
    private static final String LOGIN_URL = "http://localhost:8001/api/oauth/toLogin";

    /**
     * 过滤的具体内容
     *
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //如果是登陆的请求直接放行
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        URI uri = request.getURI();
        System.out.println(uri);
        String path = uri.getPath();
        System.out.println(path);

        //判断路径是否与登陆地址一样
        if ("/api/oauth/login".equals(path) || !UrlFilter.hasAuthorize(path)) {

            //直接放行
            return chain.filter(exchange);
        }

        //判断是否有jti
        String jti = oauthService.getJtiToCookie(request);
        if (StringUtils.isEmpty(jti)) {
            //如果jti为空,响应401，没有权限
            //   response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //然后阻止,拒绝访问
            // return response.setComplete();

            //跳转登陆页面
            return this.toLogin(LOGIN_URL,exchange);

        }


        //通过jti查询jwt
        String jwt = oauthService.getJtiToRedis(jti);
        if (StringUtils.isEmpty(jwt)) {
            //如果redis中的jwt为空

            //如果jwt为空,响应401，没有权限
//            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //然后阻止,拒绝访问
            return this.toLogin(LOGIN_URL,exchange);

        }


        //如果jwt存在，这携带jwt去访问微服务，放在头信息中
        request.mutate().header("Authorization", "Bearer " + jwt);
        //放行
        return chain.filter(exchange);
    }

    /**
     * 跳转登陆页面
     * @param loginUrl
     * @param exchange
     * @return
     */
    private Mono<Void> toLogin(String loginUrl, ServerWebExchange exchange) {
        //获取响应对象
        ServerHttpResponse response = exchange.getResponse();
        //完成跳转的状态码 302
        response.setStatusCode(HttpStatus.SEE_OTHER);
        //设置跳转的头信息
        response.getHeaders().set("Location",loginUrl);
        //拦截
        return  response.setComplete();


    }

    /**
     * 过滤的优先级
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
